package com.hans.scala.GenericTypesAndMethods

/**
 * Scala的类或特征的范型定义中，如果在类型参数前面加入+符号，就可以使类或特征变为协变了。
 * 在类型参数T前加了一个+符号
 */
class Link[+T](val head: T, val tail: Link[T]) {
//  def prepend(newHead: T): Link[T] = new Link(newHead, this)
//  范型变为协变之后就不能把类型参数不加修改的放在成员方法的参数上（这里是newHead）了
//  [U<:T]的情况下，U必须是T的子类；
//  [U>:T]的情况下，U必须是T的父类。
  def prepend[U>:T](newHead: U): Link[U] = new Link(newHead, this)
}

abstract class LessThan[-T] {
  def apply(a: T, b: T): Boolean
}


object Link {
  def main(args: Array[String]) {
    //covariant type T occurs in contravariant position in type T 
    val link: Link[Any] = new Link[String]("FOO", null)
    val link2 = link.prepend(new Object(),null)
    val link3 =  link.prepend("hans",null)
    println(link.head)
    println(link2.head)
    println(link3.head)

    //new abstract class 实现未实现的方法 
    val hashCodeLt = new LessThan[Any] {
      def apply(a: Any, b: Any): Boolean = a.hashCode <  b.hashCode
    }
    val strLT: LessThan[String] = hashCodeLt

  }
}
